/*
 * sr.c - EnCluster Standard Representation Module
 * Clunix, cezanne@clunix.com, 2005.3
 *
 * Copyright (c) 2001-2005 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "sr.h"
#include "sr_p.h"

static void fancy_print(FILE *fp, sr_t *sr, int apply_opt, ecm_uint32 level);

static const char *
get_srtstr(const sr_t *sr)
{
	const char	*srtstr;

	srtstr = srt_get_name(sr_get_type(sr));
	if (srtstr == NULL)
		srtstr = "??";
	return srtstr;
}

static void
print_indent(FILE *fp, ecm_uint32 level)
{
	ecm_uint32	i;

	for (i = 0; i < level; i++)
		ecm_fprintf(fp, "   ");
}

static void
print_srnt(FILE *fp, const sr_t *sr)
{
	const char	*srtstr, *name;

	name = sr_get_name(sr);
	srtstr = get_srtstr(sr);
	if (ecm_empty_str(name))
		ecm_fprintf(fp, "<%s> ", srtstr);
	else
		ecm_fprintf(fp, "%s <%s> ", name, srtstr);
}

static void
fancy_print_nongroup(FILE *fp, sr_t *sr, int apply_opt, ecm_uint32 level)
{
	char	*asrv;

	if (apply_opt & SR_NOT_THIS)
		return;

	print_indent(fp, level);
	print_srnt(fp, sr);
	sr_asrv_asprint(&asrv, sr_get_type(sr), sr_get_val(sr));
	ecm_fprintf(fp, "%s", asrv);
	ecm_free(asrv);
}

static void
fancy_print_child(FILE *fp, sr_t *sr, int apply_opt, ecm_uint32 level)
{
	sr_t	*sr_child;

	SR_FOREACH_CHILD(sr, NULL, sr_child) {
		fancy_print(fp, sr_child, apply_opt, level);
		ecm_fprintf(fp, ";\n");
	}
}

static void
fancy_print_group(FILE *fp, sr_t *sr, int apply_opt, ecm_uint32 level)
{
	if (!(apply_opt & SR_NOT_THIS)) {
		print_indent(fp, level);
		print_srnt(fp, sr);
		ecm_fprintf(fp, "{\n");
	}

	if (apply_opt & (SR_CHILD | SR_RECUR)) {
		int	sub_opt;
		ecm_uint32	sub_level = level;

		if (!(apply_opt & SR_NOT_THIS))
			sub_level++;
		sub_opt = apply_opt & ~SR_CHILD & ~SR_NOT_THIS;
		fancy_print_child(fp, sr, sub_opt, sub_level);
	}
	if (!(apply_opt & SR_NOT_THIS)) {
		print_indent(fp, level);
		ecm_fprintf(fp, "}");
	}
}

static void
fancy_print(FILE *fp, sr_t *sr, int apply_opt, ecm_uint32 level)
{
	if (sr_is_group(sr))
		fancy_print_group(fp, sr, apply_opt, level);
	else
		fancy_print_nongroup(fp, sr, apply_opt, level);
}

void
sr_fancy_print(FILE *fp, sr_t *sr, int apply_opt, const char *prefix)
{
	if (fp == NULL)
		return;

	if (sr == NULL) {
		ecm_fprintf(fp, "null\n");
		return;
	}
	fancy_print(fp, sr, apply_opt, 0);
	ecm_fprintf(fp, "\n");
}
